# Copyright 2020 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.

load("@rules_cc//cc:cc_library.bzl", "cc_library")
load("@rules_python//sphinxdocs:sphinx_docs_library.bzl", "sphinx_docs_library")
load("//pw_bloat:pw_size_diff.bzl", "pw_size_diff")
load("//pw_bloat:pw_size_table.bzl", "pw_size_table")
load("//pw_build:compatibility.bzl", "incompatible_with_mcu")
load("//pw_unit_test:pw_cc_test.bzl", "pw_cc_test")

package(
    default_visibility = ["//visibility:public"],
)

licenses(["notice"])

cc_library(
    name = "pw_hdlc",
    srcs = [
        "decoder.cc",
        "encoder.cc",
    ],
    hdrs = [
        "public/pw_hdlc/decoder.h",
        "public/pw_hdlc/encoded_size.h",
        "public/pw_hdlc/encoder.h",
        "public/pw_hdlc/internal/protocol.h",
    ],
    features = ["-conversion_warnings"],
    implementation_deps = ["//pw_assert:check"],
    strip_include_prefix = "public",
    deps = [
        "//pw_assert:assert",
        "//pw_bytes",
        "//pw_checksum",
        "//pw_log",
        "//pw_result",
        "//pw_span",
        "//pw_status",
        "//pw_stream",
        "//pw_varint",
    ],
)

cc_library(
    name = "rpc_channel_output",
    hdrs = ["public/pw_hdlc/rpc_channel.h"],
    features = ["-conversion_warnings"],
    strip_include_prefix = "public",
    deps = [
        ":pw_hdlc",
        "//pw_assert:assert",
        "//pw_rpc",
        "//pw_span",
    ],
)

cc_library(
    name = "default_addresses",
    hdrs = ["public/pw_hdlc/default_addresses.h"],
    strip_include_prefix = "public",
)

cc_library(
    name = "packet_parser",
    srcs = ["wire_packet_parser.cc"],
    hdrs = ["public/pw_hdlc/wire_packet_parser.h"],
    features = ["-conversion_warnings"],
    strip_include_prefix = "public",
    deps = [
        ":pw_hdlc",
        "//pw_bytes",
        "//pw_checksum",
        "//pw_router:packet_parser",
    ],
)

# A backend for pw_rpc's `system_server` that sends and receives HDLC-framed RPC
# packets over pw_sys_io.
#
# Warning: This system server is polling and blocking, so it's not
# production-ready. This exists for simplifying initial bringup/testing, and
# should not be used in any performance-sensitive application.
cc_library(
    name = "hdlc_sys_io_system_server",
    srcs = [
        "hdlc_sys_io_system_server.cc",
    ],
    implementation_deps = ["//pw_assert:check"],
    # This target uses those parts of the pw_log_basic interface which are not
    # part of the interface of pw_log itself, so it's only compatible with
    # platforms that use pw_log_basic as the pw_log backend.
    target_compatible_with = select({
        "//pw_log_basic:is_active_backend": [],
        "//conditions:default": ["@platforms//:incompatible"],
    }),
    deps = [
        ":default_addresses",
        ":pw_hdlc",
        ":rpc_channel_output",
        "//pw_log",
        "//pw_log_basic:extension",
        "//pw_rpc/system_server:facade",
        "//pw_status",
        "//pw_stream:sys_io_stream",
    ],
)

pw_cc_test(
    name = "encoder_test",
    srcs = ["encoder_test.cc"],
    features = ["-conversion_warnings"],
    deps = [
        ":pw_hdlc",
        "//pw_bytes",
        "//pw_stream",
    ],
)

pw_cc_test(
    name = "decoder_test",
    srcs = ["decoder_test.cc"],
    features = [
        "-conversion_warnings",
        "-ctad_warnings",
    ],
    deps = [
        ":pw_hdlc",
        "//pw_bytes",
        "//pw_fuzzer:fuzztest",
        "//pw_result",
        "//pw_stream",
    ],
)

pw_cc_test(
    name = "encoded_size_test",
    srcs = ["encoded_size_test.cc"],
    features = ["-conversion_warnings"],
    deps = [
        ":pw_hdlc",
        "//pw_bytes",
        "//pw_result",
        "//pw_stream",
        "//pw_varint",
    ],
)

pw_cc_test(
    name = "wire_packet_parser_test",
    srcs = ["wire_packet_parser_test.cc"],
    features = ["-conversion_warnings"],
    deps = [
        ":packet_parser",
        ":pw_hdlc",
        "//pw_bytes",
    ],
)

pw_cc_test(
    name = "rpc_channel_test",
    srcs = ["rpc_channel_test.cc"],
    features = ["-conversion_warnings"],
    deps = [
        ":pw_hdlc",
        ":rpc_channel_output",
        "//pw_bytes",
        "//pw_stream",
    ],
)

cc_library(
    name = "router",
    srcs = ["router.cc"],
    hdrs = ["public/pw_hdlc/router.h"],
    features = ["-conversion_warnings"],
    strip_include_prefix = "public",
    deps = [
        ":pw_hdlc",
        "//pw_async2:dispatcher",
        "//pw_async2:poll",
        "//pw_bytes",
        "//pw_channel",
        "//pw_containers:vector",
        "//pw_log",
        "//pw_multibuf",
        "//pw_multibuf:allocator",
        "//pw_multibuf:stream",
        "//pw_result",
        "//pw_status",
        "//pw_stream",
    ],
)

pw_cc_test(
    name = "router_test",
    srcs = ["router_test.cc"],
    features = [
        "-conversion_warnings",
        "-ctad_warnings",
    ],
    deps = [
        ":router",
        "//pw_allocator:testing",
        "//pw_async2:pend_func_task",
        "//pw_bytes",
        "//pw_channel:forwarding_channel",
        "//pw_channel:loopback_channel",
        "//pw_containers:inline_queue",
        "//pw_containers:vector",
        "//pw_multibuf:simple_allocator",
    ],
)

filegroup(
    name = "doxygen",
    srcs = [
        "public/pw_hdlc/decoder.h",
        "public/pw_hdlc/encoder.h",
        "public/pw_hdlc/router.h",
    ],
)

pw_size_diff(
    name = "full_size_diff",
    base = "//pw_hdlc/size_report:base",
    label = "HDLC encode and decode",
    target = "//pw_hdlc/size_report:full",
)

pw_size_diff(
    name = "full_crc_size_diff",
    base = "//pw_hdlc/size_report:base_crc",
    label = "HDLC encode and decode, ignoring CRC and varint",
    target = "//pw_hdlc/size_report:full_crc",
)

pw_size_table(
    name = "pw_hdlc_size_table",
    reports = [
        ":full_size_diff",
        ":full_crc_size_diff",
    ],
)

sphinx_docs_library(
    name = "docs",
    srcs = [
        "Kconfig",
        "api.rst",
        "design.rst",
        "docs.rst",
        "guide.rst",
        "router.rst",
        "size.rst",
        ":pw_hdlc_size_table",
        "//pw_hdlc/rpc_example:docs",
    ],
    prefix = "pw_hdlc/",
    target_compatible_with = incompatible_with_mcu(),
)
